#include <iostream>
#include <omp.h>

// 定义类T，包含静态成员变量i并使用threadprivate声明
class T {
public:
    static int i;
    #pragma omp threadprivate(i)
    
    // 构造函数
    T() {
        #pragma omp critical
        {
            std::cout << "T构造函数被调用 (线程" << omp_get_thread_num() << ")" << std::endl;
        }
    }
    
    // 析构函数
    ~T() {
        #pragma omp critical
        {
            std::cout << "T析构函数被调用 (线程" << omp_get_thread_num() << ")" << std::endl;
        }
    }
    
    // 静态方法，用于操作静态成员i
    static void increment() {
        i++;
    }
    
    static void setValue(int value) {
        i = value;
    }
    
    static int getValue() {
        return i;
    }
};

// 初始化静态成员变量
int T::i = 0;

int main() {
    int num_threads = 4;
    omp_set_num_threads(num_threads);
    
    std::cout << "===== OpenMP threadprivate在类中的应用示例 =====" << std::endl;
    
    // 显示初始值
    std::cout << "\n主线程中的初始值：" << std::endl;
    std::cout << "T::i = " << T::i << std::endl;
    
    // 修改主线程中的值
    T::setValue(100);
    
    std::cout << "\n修改后主线程中的值：" << std::endl;
    std::cout << "T::i = " << T::getValue() << std::endl;
    
    // 第一个并行区域 - 测试threadprivate静态成员
    std::cout << "\n===== 第一个并行区域 =====" << std::endl;
    #pragma omp parallel
    {
        int tid = omp_get_thread_num();
        
        #pragma omp critical
        {
            std::cout << "线程 " << tid << " 的初始值：T::i = " << T::i << std::endl;
        }
        
        // 修改线程私有静态成员
        T::setValue(1000 + tid);
        
        #pragma omp critical
        {
            std::cout << "线程 " << tid << " 修改后的值：T::i = " << T::getValue() << std::endl;
        }
        
        // 再次增加值
        for (int j = 0; j < 3; j++) {
            T::increment();
        }
        
        #pragma omp critical
        {
            std::cout << "线程 " << tid << " 增加3次后的值：T::i = " << T::getValue() << std::endl;
        }
    }
    
    // 检查主线程的值是否被影响
    std::cout << "\n第一个并行区域后主线程的值：" << std::endl;
    std::cout << "T::i = " << T::getValue() << std::endl;
    
    // 创建类实例
    std::cout << "\n===== 创建类实例 =====" << std::endl;
    T t1, t2;
    
    std::cout << "通过实例t1访问：T::i = " << T::i << std::endl;
    
    // 第二个并行区域 - 测试类实例与threadprivate
    std::cout << "\n===== 第二个并行区域 =====" << std::endl;
    #pragma omp parallel
    {
        int tid = omp_get_thread_num();
        
        // 创建线程内的类实例
        T t_local;
        
        #pragma omp critical
        {
            std::cout << "线程 " << tid << " 初始值：T::i = " << T::i << std::endl;
        }
        
        // 通过实例修改静态成员
        t_local.setValue(2000 + tid);
        
        #pragma omp critical
        {
            std::cout << "线程 " << tid << " 修改后的值：T::i = " << t_local.getValue() << std::endl;
        }
    }
    
    // 最终检查
    std::cout << "\n最终主线程的值：" << std::endl;
    std::cout << "T::i = " << T::getValue() << std::endl;
    std::cout << "通过实例t1访问：t1.i = " << t1.i << std::endl;
    std::cout << "通过实例t2访问：t2.i = " << t2.i << std::endl;
    
    return 0;
}